﻿using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using IssueIT.Core.Configuration.Settings;
using IssueIT.Core.Infrastructure.Logging;
using IssueIT.Core.Services;
using IssueIT.Core.Util;
using IssueIT.WebUI.Controllers;
using StructureMap;
using StructureMap.Configuration.DSL;
using StructureMap.Graph;

namespace IssueIT.WebUI.Infrastructure
{
	public class IssueApplication : HttpApplication
	{
		protected void Application_Start()
		{
			Bootstrap();

			AreaRegistration.RegisterAllAreas();

			RegisterGlobalFilters(GlobalFilters.Filters);
			RegisterRoutes(RouteTable.Routes);
		}

		private static void Bootstrap()
		{
			ObjectFactory.Initialize(cfg =>
			{
				cfg.For<ILogger>().Use<NoLogging>();
				//cfg.ForSingletonOf<ImageSettings>().Use<ImageSettings>();

				// move to e.g. AppSettingsRegistry?
				cfg.For<IObjectConverter>().Use<ObjectConverter>();
				cfg.For<ISettingsAdapter>().Use<AppSettingsAdapter>();
				cfg.For<ISettingsNamingConvention>().Use<DefaultSettingsNamingConvention>();
				cfg.For<IConversionIssueReporter>().Use<ConversionIssueReporter>();
				cfg.For<ISettingsBuilder>().Use<SettingsBuilder>();
                cfg.For<IProjectService>().Use<ProjectService>();
                
				cfg.Scan(scan =>
				{
					scan.AssemblyContainingType<ImageSettings>();
					scan.AddAllTypesOf<ISettings>();
					scan.Convention<SettingsRegistrationConvention>();
				});

				cfg.Scan(scan =>
				{
					scan.AssemblyContainingType<IssueBaseController>();
					scan.AddAllTypesOf<IController>();
				});
			});

			DependencyResolver.SetResolver(new StructureMapDependencyResolver(ObjectFactory.Container));
		}

		public class SettingsRegistrationConvention : IRegistrationConvention
		{
			public void Process(Type type, Registry registry)
			{
				if( !type.IsInterface && !type.IsAbstract && typeof(ISettings).IsAssignableFrom(type) )
				{
					registry.For(type).EnrichWith((context, settingsInstance) =>
					{
						var settingsBuilder = context.GetInstance<ISettingsBuilder>();
						settingsBuilder.BuildSettings((ISettings) settingsInstance);
						return settingsInstance;
					}).Singleton().Use(type);
				}
			}
		}

		public static void RegisterGlobalFilters(GlobalFilterCollection filters)
		{
			filters.Add(new HandleErrorAttribute());
		}

		public static void RegisterRoutes(RouteCollection routes)
		{
			routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
			routes.IgnoreRoute("{*favicon}", new {favicon = @"(.*/)?favicon.ico(/.*)?"});

			ImageSettings settings = new ImageSettings();

			routes.MapRoute(
				"Image",
				"image/{id}/{size}/{slug}.jpg",
				new {controller = "Image", action = "Get", slug = "Image"},
				new {size = string.Join("|", settings.GetImageSizeNames().ToArray())}
				);

			routes.MapRoute(
				"ProjectList", // Route name
				"{project}", // URL with parameters
				new {controller = "Project", action = "Index"} // Parameter defaults
				);

			routes.MapRoute(
				"ProjectListFiltred", // Route name
				"{project}/{type}/{filer}", // URL with parameters
				new {controller = "Project", action = "Index"} // Parameter defaults
				);

			routes.MapRoute(
				"AddIssue", // Route name
				"{project}/add", // URL with parameters
				new {controller = "Issue", action = "Add"} // Parameter defaults
				);
			/*
            routes.MapRoute(
                "Project", // Route name
                "{project}/{action}/{id}", // URL with parameters
                new {controller = "Project", action = "Index", id = UrlParameter.Optional} // Parameter defaults
            );
            */
			routes.MapRoute(
				"Default", // Route name
				"{controller}/{action}/{id}", // URL with parameters
				new {controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
				);
		}
	}
}